package io.bdmc.core.snmp;

import java.util.ArrayList;

import java.util.Iterator;
import java.util.List;

 

public class GwUtil {

 
    private static String hexStr =  "0123456789ABCDEF";
    private static String[] binaryArray =   
        {"0000","0001","0010","0011",  
        "0100","0101","0110","0111",  
        "1000","1001","1010","1011",  
        "1100","1101","1110","1111"}; 


    public static byte[] strToByteArray(String str) {
        if (str == null) {
            return null;
        }
        byte[] byteArray = str.getBytes();
        return byteArray;
    }


    public static String byteArrayToStr(byte[] byteArray) {
        if (byteArray == null) {
            return null;
        }
        String str = new String(byteArray);
        return str;
    }

    public static String padLeft(String src, int len, char ch) {
        int diff = len - src.length();
        if (diff <= 0) {
            return src;
        }

        char[] charr = new char[len];
        System.arraycopy(src.toCharArray(), 0, charr, 0, src.length());
        for (int i = src.length(); i < len; i++) {
            charr[i] = ch;
        }
        return new String(charr);
    }
   
    public static String padRight(String src, int len, char ch) {
        int diff = len - src.length();
        if (diff <= 0) {
            return src;
        }

        char[] charr = new char[len];
        System.arraycopy(src.toCharArray(), 0, charr, diff, src.length());
        for (int i = 0; i < diff; i++) {
            charr[i] = ch;
        }
        return new String(charr);
    }
  
    public static String StrToHex(String chineseStr) throws Exception {
        StringBuffer GBKStr = new StringBuffer();
        byte[] GBKDecode = chineseStr.getBytes("gbk");
        for (byte b : GBKDecode)
            GBKStr.append(Integer.toHexString(b & 0xFF));
        return GBKStr.toString().toUpperCase();
    }

 
    public static String GBK2Str(String GBKStr) throws Exception {
        byte[] b = HexString2Bytes(GBKStr);
        String chineseStr = new String(b, "gbk");
        return chineseStr;
    }

  
    public static byte[] HexString2Bytes(String hexStr) {
        byte[] b = new byte[hexStr.length() / 2];
        for (int i = 0; i < b.length; i++)
            b[i] = (byte) Integer.parseInt(hexStr.substring(2 * i, 2 * i + 2), 16);
        return b;
    }

   
    public static final String bytesToHexString(byte[] byteArray) {
        StringBuffer hexStr = new StringBuffer(byteArray.length * 2);
        for (int i = 0; i < byteArray.length; i++) {
            String sTemp = Integer.toHexString(0xFF & byteArray[i]);
            int j = 0;
            while (j < 2 - sTemp.length()) {
                sTemp = "0" + sTemp;
                j++;
            }
            hexStr.append(sTemp.toUpperCase());
        }
        return hexStr.toString();
    }

   
    public static String byte2Hex(byte b) {

        String hex = Integer.toHexString(b & 0xFF);
        if (hex.length() == 1) {
            hex = '0' + hex;

            return hex.toUpperCase();
        }
        return hex;

    }

   
    public static byte getXor(byte[] datas) {

        byte temp = datas[1];

        for (int i = 2; i < datas.length - 2; i++) {
            temp ^= datas[i];
        }

        return temp;
    }

   
    public static String bcd2Str(byte[] bytes) {
        StringBuffer temp = new StringBuffer(bytes.length * 2);
        for (int i = 0; i < bytes.length; i++) {
            temp.append((byte) ((bytes[i] & 0xf0) >>> 4));
            temp.append((byte) (bytes[i] & 0x0f));
        }
        return temp.toString().substring(0, 1).equalsIgnoreCase("0") ? temp.toString().substring(1) : temp.toString();
    }

  
    public static byte[] str2Bcd(String asc) {
        int len = asc.length();
        int mod = len % 2;
        if (mod != 0) {
            asc = "0" + asc;
            len = asc.length();
        }
        byte abt[] = new byte[len];
        if (len >= 2) {
            len = len / 2;
        }
        byte bbt[] = new byte[len];
        abt = asc.getBytes();
        int j, k;
        for (int p = 0; p < asc.length() / 2; p++) {
            if ((abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {
                j = abt[2 * p] - '0';
            } else if ((abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {
                j = abt[2 * p] - 'a' + 0x0a;
            } else {
                j = abt[2 * p] - 'A' + 0x0a;
            }
            if ((abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {
                k = abt[2 * p + 1] - '0';
            } else if ((abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {
                k = abt[2 * p + 1] - 'a' + 0x0a;
            } else {
                k = abt[2 * p + 1] - 'A' + 0x0a;
            }
            int a = (j << 4) + k;
            byte b = (byte) a;
            bbt[p] = b;
        }
        return bbt;
    }
    public static String HexToBin(String hex)
    {
        return bytes2BinStr(hexStr2BinArr(hex));
    }
    public static String bytes2BinStr(byte[] bArray)
    {  

        String outStr = "";  
        int pos = 0;  
        for(byte b:bArray){  
            //高四位  
            pos = (b&0xF0)>>4;  
            outStr+=binaryArray[pos];  
            //低四位  
            pos=b&0x0F;  
            outStr+=binaryArray[pos];  
        }  
        return outStr;  
    }  
    public static byte[] hexStr2BinArr(String hexString){  
        //hexString的长度对2取整，作为bytes的长度  
        int len = hexString.length()/2;  
        byte[] bytes = new byte[len];  
        byte high = 0;//字节高四位  
        byte low = 0;//字节低四位  
        for(int i=0;i<len;i++){  
             //右移四位得到高位  
             high = (byte)((hexStr.indexOf(hexString.charAt(2*i)))<<4);  
             low = (byte)hexStr.indexOf(hexString.charAt(2*i+1));  
             bytes[i] = (byte) (high|low);//高地位做或运算  
        }  
        return bytes;  
    }

 
    public static long DWord2long(byte[] bytes) {

        long addr;
        if (bytes.length == 1) {
            addr = bytes[0] & 0xFF;
        } else {
            addr = bytes[3] & 0xFF;
            addr = (addr << 8) | (bytes[2] & 0xff);
            addr = (addr << 8) | (bytes[1] & 0xff);
            addr = (addr << 8) | (bytes[0] & 0xff);
        }
        return addr;
    }
    
    public static int DWord2Int(byte[] bytes) {

        int addr;
        if (bytes.length == 1) {
            addr = bytes[0] & 0xFF;
        } else {
            addr = bytes[3] & 0xFF;
            addr = (addr << 8) | (bytes[2] & 0xff);
            addr = (addr << 8) | (bytes[1] & 0xff);
            addr = (addr << 8) | (bytes[0] & 0xff);
        }
        return addr;
    }

    public static int Word2Int(byte[] bytes) {

        int addr;
        if (bytes.length == 1) {
            addr = bytes[0] & 0xFF;
        } else {
            addr = bytes[1] & 0xFF;
            addr = (addr << 8) | (bytes[0] & 0xff);
        }
        return addr;
    }

    /**
     * 字节数组拆分
     *
     * @param paramArrayOfByte 原始数组
     * @param paramInt1        起始下标
     * @param paramInt2        要截取的长度
     * @return 处理后的数组
     */
    public static byte[] SubArray(byte[] paramArrayOfByte, int paramInt1, int paramInt2) {
        byte[] arrayOfByte = new byte[paramInt2];
        int i = 0;
        while (true) {
            if (i >= paramInt2)
                return arrayOfByte;
            arrayOfByte[i] = paramArrayOfByte[(i + paramInt1)];
            i += 1;
        }
    }


    public static byte[] Int2Bytes_LE(int iValue) {
        byte[] rst = new byte[2];
      
        rst[0] = (byte) ((iValue & 0xFF00) >> 8);
    
        rst[1] = (byte) (iValue & 0xFF);
        return rst;
    }

    public static byte[] Int2Bytes1_LE(int iValue) {
        byte[] rst = new byte[4];

        rst[0] = (byte) ((iValue & 0xFF000000) >> 24);
        rst[1] = (byte) ((iValue & 0xFF0000) >> 16);
        rst[2] = (byte) ((iValue & 0xFF00) >> 8);
        rst[3] = (byte) (iValue & 0xFF);
        return rst;
    }
    public static byte[] Int2Bytes1_LE(long iValue) {
        byte[] rst = new byte[4];

        rst[0] = (byte) ((iValue & 0xFF000000) >> 24);
        rst[1] = (byte) ((iValue & 0xFF0000) >> 16);
        rst[2] = (byte) ((iValue & 0xFF00) >> 8);
        rst[3] = (byte) (iValue & 0xFF);
        return rst;
    }
    public static byte[] ProcessTransferredRequest(byte[] buffers) {
        // 数据转义
        List<Byte> bytes = new ArrayList<Byte>();
        for (int i = 0; i < buffers.length; i++) {
            if (buffers[i] == 0x7D) {
                if (i == buffers.length - 1) {
                    bytes.add(buffers[i]);
                } else {
                    if (buffers[i + 1] == 0x01) {
                        bytes.add((byte) 0x7D);

                        i++;
                    } else if (buffers[i + 1] == 0x02) {
                        bytes.add((byte) 0x7E);
                        i++;
                    } else {
                        bytes.add(buffers[i]);
                    }
                }
            } else {
                bytes.add(buffers[i]);
            }
        }
        byte[] result = new byte[bytes.size()];
        for (int i = 0; i < bytes.size(); i++) {
            result[i] = bytes.get(i);
        }
        return result;
    }


    public static byte[] Long2Bytes_LE(long iValue) {
        byte[] rst = new byte[4];

        rst[0] = (byte) ((iValue & 0xFF000000) >> 24);
        rst[1] = (byte) ((iValue & 0xFF0000) >> 16);
        rst[2] = (byte) ((iValue & 0xFF00) >> 8);
        rst[3] = (byte) (iValue & 0xFF);
        return rst;
    }


    public static String strAddZero_left(String str, int strLength) {
        int strLen = str.length();
        if (strLen < strLength) {
            while (strLen < strLength) {
                StringBuffer sb = new StringBuffer();
                sb.append("0").append(str);

                str = sb.toString();
                strLen = str.length();
            }
        }

        return str;
    }


    public static String strAddZero_right(String str, int strLength) {
        int strLen = str.length();
        if (strLen < strLength) {
            while (strLen < strLength) {
                StringBuffer sb = new StringBuffer();

                sb.append(str).append("0");//
                str = sb.toString();
                strLen = str.length();
            }
        }

        return str;
    }


    public static String GetCheckCode(String s) {
     
        byte[] buffers = HexString2Bytes(s);
        byte x = buffers[0];
        for (int i = 1; i < buffers.length; i++) {
            x = (byte) (x ^ buffers[i]);
        }
        return byte2Hex(x);

    }


    public static int HexToInt(String hex) {
        return Integer.valueOf(hex, 16);
    }

    public static long HexTolong(String hex) {
        return Long.valueOf(hex, 16);
    }

    public static byte[] BuildTransferredRequest(byte[] buffers) {

        List<Byte> bytesLt = new ArrayList<Byte>();
        for (Byte i = 0; i < buffers.length; i++) {
            if (buffers[i] == 0x7E) {
                bytesLt.add((byte) 0x7D);
                bytesLt.add((byte) 0x02);
            } else if (buffers[i] == 0x7D) {
                bytesLt.add((byte) 0x7D);
                bytesLt.add((byte) 0x01);
            } else {
                bytesLt.add(buffers[i]);
            }
        }
        return listTobyte11(bytesLt);
    }

   
    public static byte[] rebackData(byte[] data) {
        List<Byte> dataList = new ArrayList<>();
        for (int i = 0; i < data.length; i++) {
            if (i < data.length - 1) {
                if (data[i] == (byte) 0x7d && data[i + 1] == (byte) 0x02) {
                    dataList.add((byte) 0x7e);
                } else if (data[i] == (byte) 0x7d && data[i + 1] == (byte) 0x01) {
                    dataList.add((byte) 0x7d);
                } else {
                    dataList.add(data[i]);
                }
            } else {
                dataList.add(data[i]);
            }
        }

        byte[] result = new byte[dataList.size()];
        for (int i = 0; i < dataList.size(); i++) {
            result[i] = dataList.get(i);
        }
        return result;
    }
    public static String Bytes2String(String buf, int startindex, int len) throws Exception
    {
        return GwUtil.HexToStr(buf.substring(startindex, startindex+len));
    }


    public static String IntToHex(int n, int len) {
        StringBuilder sb = new StringBuilder();
        sb.append(Integer.toHexString(n).toUpperCase());
        while (sb.length() < len) {
            sb.insert(0, "0");
        }
        return sb.toString();
    }

  
    private static byte[] listTobyte11(List<Byte> list) {
        if (list == null || list.size() < 0)
            return null;
        byte[] bytes = new byte[list.size()];
        int i = 0;
        Iterator<Byte> iterator = list.iterator();
        while (iterator.hasNext()) {
            bytes[i] = iterator.next();
            i++;
        }
        return bytes;
    }

  
    public static boolean ValidateCheckCode(byte[] buffers) {
        // if (buffers.length < 2) return false;
        // byte x = buffers[1];
        // for (int i = 2; i < buffers.length - 2; i++)
        // {
        // x = (byte)(x ^ buffers[i]);
        // }
        // return x ==buffers[buffers.length - 2];

        if (buffers.length < 1)
            return false;
        byte x = buffers[0];
        for (int i = 1; i < buffers.length - 1; i++) {
            x = (byte) (x ^ buffers[i]);
        }
        return x == buffers[buffers.length - 1];
    }

  
    public static byte[] subBytes(byte[] src, int begin, int count) {
        byte[] bs = new byte[count];
        for (int i = begin; i < begin + count; i++)
            bs[i - begin] = src[i];
        return bs;
    }

    public static byte[] add(byte[] data1, byte[] data2) {

        byte[] result = new byte[data1.length + data2.length];
        System.arraycopy(data1, 0, result, 0, data1.length);
        System.arraycopy(data2, 0, result, data1.length, data2.length);
        return result;
    }

	public static String HexToStr(String value) throws Exception {
		return GBK2Str(value);
	}

	public static String StrToHex(String str, int len) throws Exception {
        String ret = StrToHex(str);
        if (ret.length() > len)
            ret = ret.substring(0, len);
        else
        {
            while (ret.length() < len)
                ret = "0" + ret;
        }
        return ret;
	}

	

}
